工具&方法丨菜鸟升级打怪系列之python代码优化(2)
前言
正文
import numpy as np
import pandas as pd
import math
# 随机生成33333行3列DataFrame
arr = np.random.choice(99999, size=99999).reshape(-1, 3)
num_df = pd.DataFrame(arr, columns=['x', 'y', 'z'])
左右滑动查看更多
def calculate(x,y,z):
"""
三个数字的简单数学计算
"""
res = math.sqrt(x) + math.sqrt(y) - math.sqrt(z)
return res
num_df1 = num_df.copy()
for j in num_df.index: # 按照DataFrame的索引取数据
xyz_num = num_df.loc[j, ['x', 'y', 'z']] # 取出需要计算的数据
res = calculate(xyz_num['x'], xyz_num['y'], xyz_num['z'])
num_df1.loc[j, 'res'] = res
# pandas.Series.apply示例
res = num_df.loc[:,'z'].apply(lambda z_num: z_num + 1) # 对每个index的数据加1
print(type(res)) # <class 'pandas.core.series.Series'>
左右滑动查看更多
# pandas.DataFrame.apply示例1
res1 = num_df.apply(lambda num: num+1, axis=1)
print(type(res1)) # <class 'pandas.core.frame.DataFrame'>
左右滑动查看更多
# pandas.DataFrame.apply示例2
res2 = num_df.apply(lambda col:sum(col), axis=0)
print(type(res2)) # <class 'pandas.core.series.Series'>
左右滑动查看更多
# pandas.DataFrame.apply示例3
res3 = num_df.apply(lambda col:sum(col), axis=1)
左右滑动查看更多
num_df1['res'] = num_df.apply(lambda ser: calculate(ser['x'], ser['y'], ser['z']),axis=1)
res = pd.Series([])
# 1.使用for循环求和
start_time = time.time()
for i in num_df.index:
res.loc[i] = sum(num_df.loc[i,:])
print(res)
print(time.time()-start_time) # 运行时间为:33.4246723651886s
# 2.使用DataFrame的内部函数DataFrame.sum
start_time = time.time()
print(num_df.sum(axis=1))
print(time.time()-start_time) # 运行时间为:0.003989696502685547s
# 3.使用apply
start_time = time.time()
print(num_df.apply(lambda col:sum(col), axis=1))
print(time.time()-start_time) # 运行时间为:0.38198184967041016s
左右滑动查看更多
总的来说:
for循环无疑是效率最低的;
当对象有相应的内部函数时尽量使用内部函数;
apply方法适用于较复杂算法的情景。
关于apply的更多参数,可以去查看一下官方文档👇
Series.apply(func, convert_dtype=True, args=(), **kwds)
Invoke function on values of Series.
Can be ufunc (a NumPy function that applies to the entire Series) or a Python function that only works on single values.
►https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.apply.html#pandas.Series.apply
DataFrame.apply(self, func, axis=0, broadcast=None, raw=False, reduce=None, result_type=None, args=(), **kwds)
Apply a function along an axis of the DataFrame.
Objects passed to the function are Series objects whose index is either the DataFrame’s index (axis=0) or the DataFrame’s columns (axis=1). By default (result_type=None), the final return type is inferred from the return type of the applied function. Otherwise, it depends on the result_type argument.
►https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.apply.html
df = pd.DataFrame({'A':['a','b','a','c'],
'B':['c','d','d','a'],
'C':['x','x','f','b']})
print(df.groupby(['A'])) # <pandas.core.groupby.groupby.DataFrameGroupBy object at 0x000000B0137ED6A0>
左右滑动查看更多
for name, group in df.groupby(['A']):
print(name) # 遍历该分组内的组名
print(group) # 遍历该组内的组成员
print(type(group), '\n')
左右滑动查看更多
a
A B C
0 a c x
2 a d f
<class 'pandas.core.frame.DataFrame'>
b
A B C
1 b d x
<class 'pandas.core.frame.DataFrame'>
c
A B C
3 c a b
<class 'pandas.core.frame.DataFrame'>
左右滑动查看更多
可以看到,按照“A”列分出的三个组被分别存放为DataFrame的形式。这就有点突然对DataFrame.groupby.apply方法有了更深一些的认知,我猜想是“依次取出每一个类别下的DataFrame进行操作”。
遂:
# DataFrame.to_dict方法将DataFrame转化成字典
dict0 = df.groupby(['A']).apply(lambda
df:df.reset_index(drop=True).to_dict('index'))
print(dict0)
左右滑动查看更多
A
a {0: {'A': 'a', 'B': 'c', 'C': 'x'}, 1: {'A': '...
b {0: {'A': 'b', 'B': 'd', 'C': 'x'}}
c {0: {'A': 'c', 'B': 'a', 'C': 'b'}}
dtype: object
左右滑动查看更多
果不其然!每个类别下的DataFrame都变成了字典并存放在了索引为他们的组名的Series里。
结语
python表格处理的三个(大概是?)常用对象的apply方法就是这些啦。虽然只是用了很简单的例子来举例,但是以小见大,肯定能够有用得上的时候!除此之外pandas库的方法还有很多,我也还在熟悉阶段,相信多学习多接触就可以继续开辟新大陆!
►往期推荐
回复【Python】👉 简单有用易上手
回复【学术前沿】👉机器学习丨大数据
回复【数据资源】👉公开数据
回复【可视化】👉 你心心念念的数据呈现
回复【老姚专栏】👉老姚趣谈值得一看
►一周热文
工具&方法 | 6张卡片,2分钟,轻松掌握R命令大集合(推荐收藏备用)
数据Seminar
这里是大数据、分析技术与学术研究的三叉路口
欢迎扫描👇二维码添加关注